{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Project 1: TimeZone class"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's start with the timezone class. This one will have two instance attributes, offset and name. I'm going to create those as read-only properties. Offsets should be provided as a timespan (timedelta) of hours and minutes - we'll allow specifying the hour and minute offsets separately in the __init__, but the offset property will combine those as a timespan object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numbers\n",
    "from datetime import timedelta\n",
    "\n",
    "\n",
    "class TimeZone:\n",
    "    def __init__(self, name, offset_hours, offset_minutes):\n",
    "        if name is None or len(str(name).strip()) == 0:\n",
    "            raise ValueError('Timezone name cannot be empty.')\n",
    "            \n",
    "        self._name = str(name).strip()\n",
    "        \n",
    "        if not isinstance(offset_hours, numbers.Integral):\n",
    "            raise ValueError('Hour offset must be an integer.')\n",
    "        \n",
    "        if not isinstance(offset_minutes, numbers.Integral):\n",
    "            raise ValueError('Minutes offset must be an integer.')\n",
    "            \n",
    "        if offset_minutes < -59 or offset_minutes > 59:\n",
    "            raise ValueError('Minutes offset must between -59 and 59 (inclusive).')\n",
    "            \n",
    "        # for time delta sign of minutes will be set to sign of hours\n",
    "        offset = timedelta(hours=offset_hours, minutes=offset_minutes)\n",
    "\n",
    "        # offsets are technically bounded between -12:00 and 14:00\n",
    "        # see: https://en.wikipedia.org/wiki/List_of_UTC_time_offsets\n",
    "        if offset < timedelta(hours=-12, minutes=0) or offset > timedelta(hours=14, minutes=0):\n",
    "            raise ValueError('Offset must be between -12:00 and +14:00.')\n",
    "            \n",
    "        self._offset_hours = offset_hours\n",
    "        self._offset_minutes = offset_minutes\n",
    "        self._offset = offset\n",
    "        \n",
    "    @property\n",
    "    def offset(self):\n",
    "        return self._offset\n",
    "    \n",
    "    @property\n",
    "    def name(self):\n",
    "        return self._name\n",
    "    \n",
    "    def __eq__(self, other):\n",
    "        return (isinstance(other, TimeZone) and \n",
    "                self.name == other.name and \n",
    "                self._offset_hours == other._offset_hours and\n",
    "                self._offset_minutes == other._offset_minutes)\n",
    "    def __repr__(self):\n",
    "        return (f\"TimeZone(name='{self.name}', \"\n",
    "                f\"offset_hours={self._offset_hours}, \"\n",
    "                f\"offset_minutes={self._offset_minutes})\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's try it out and make sure it's working:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "tz1 = TimeZone('ABC', -2, -15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'ABC'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tz1.name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2019-06-02 23:27:15.937254\n"
     ]
    }
   ],
   "source": [
    "from datetime import datetime\n",
    "\n",
    "dt = datetime.utcnow()\n",
    "print(dt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2019-06-02 21:12:15.937254\n"
     ]
    }
   ],
   "source": [
    "print(dt + tz1.offset)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we can see the offset seems to be working (-2:15 from current time)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(We really should be writing unit tests as we write our code - but I'll show you unit tests in the last section of this project, and next project we can code and unit test in parallel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
